package com.erp.app.common.VUtil.sql;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
import java.util.HashMap;
import java.util.Map;

public class ATableStructureDumper implements ITableStructureDumper {
    protected Connection conn;
    protected boolean bClustered = false;
    protected String sCatalog = null, sSchema = null;
    protected int iPK = 6, iColumn = 4, iSeq = 5;

    public ATableStructureDumper(Connection conn) throws SQLException {
        this.conn = conn;
        DatabaseMetaData dbmd = conn.getMetaData();
        sCatalog = conn.getCatalog();
    }

    public void finalize() {
        conn = null;
    }

    public boolean isEffectiveRow(ResultSet rs) throws SQLException {
        return rs.getRow() > 0;
    }

    public String getColumns(ResultSetMetaData md, String sTable) throws SQLException {
        StringBuffer sb = new StringBuffer();
        sb.append("    " + getLine(md, 1));
        for (int j = 2; j <= md.getColumnCount(); j++)
            sb.append(",\r\n    " + getLine(md, j));
        return sb.toString();
    }

    public ResultSet getIndexInfo(ResultSet rs) throws SQLException {
        while (rs.next() && null == rs.getString(6))
            ;
        if (isEffectiveRow(rs))
            bClustered = DatabaseMetaData.tableIndexClustered == rs.getShort(7);
        return null;
    }

    public Map getPrimaryKeys(String sTable) throws SQLException {
        DatabaseMetaData dbmd = conn.getMetaData();
        ResultSet rs = dbmd.getIndexInfo(null, null, sTable, true, false);
        rs = getIndexInfo(rs);
        if (null == rs) {
            rs = dbmd.getPrimaryKeys(sCatalog, sSchema, sTable);
            rs.next();
        }
        HashMap h = new HashMap();
        h.put(PK_NAME, rs.getString(6));
        h.put(SHOW_PK_NAME, "PK_" + sTable);
        if (isEffectiveRow(rs)) {
            do {
                h.put(new Integer(rs.getShort(iSeq)), rs.getString(iColumn));
            } while (rs.next());
        }
        return h;
    }

    public String getConstraintLine(Map h) {
        return "CONSTRAINT " + h.get(SHOW_PK_NAME) + " PRIMARY KEY " + (!bClustered ? "NON" : "") + "CLUSTERED";
    }

    public String getLine(ResultSetMetaData md, int iRow) throws SQLException {
        return md.getColumnName(iRow) + "    " + getColumnTypeName(md, iRow)
                + (md.columnNoNulls == md.isNullable(iRow) ? " NOT" : "") + " NULL";
    }

    public String getColumnTypeName(ResultSetMetaData md, int i) throws SQLException {
        boolean bDisplay = true, bScale = false;
        String sColumn = md.getColumnTypeName(i);
        switch (md.getColumnType(i)) {
            case Types.LONGVARBINARY:
            case Types.INTEGER:
            case Types.SMALLINT:
            case Types.TIMESTAMP:
                bDisplay = false;
                break;
            case Types.DECIMAL:
                sColumn = md.getColumnTypeName(Types.NUMERIC);
            case Types.NUMERIC:
                bScale = true;
                break;
            default:
        // System.out.println("type = " + i );
        }
        return sColumn
                + "    "
                + (bDisplay ? "(" + (bScale ? md.getPrecision(i) : md.getColumnDisplaySize(i))
                        + (bScale ? "," + md.getScale(i) : "") + ")" : "");
    }
}
